/*---------------------------------------------------------------------------------------------
 *  Copyright (c) Microsoft Corporation. All rights reserved.
 *  Licensed under the MIT License. See License.txt in the project root for license information.
 *--------------------------------------------------------------------------------------------*/
'use strict';
/* eslint-disable */
import { vscMockPosition } from './position';
import { vscMockRange } from './range';
export namespace vscMockSelection {
    /**
     * A selection in the editor.
     * The selection is a range that has an orientation.
     */
    export interface ISelection {
        /**
         * The line number on which the selection has started.
         */
        readonly selectionStartLineNumber: number;
        /**
         * The column on `selectionStartLineNumber` where the selection has started.
         */
        readonly selectionStartColumn: number;
        /**
         * The line number on which the selection has ended.
         */
        readonly positionLineNumber: number;
        /**
         * The column on `positionLineNumber` where the selection has ended.
         */
        readonly positionColumn: number;
    }

    /**
     * The direction of a selection.
     */
    export enum SelectionDirection {
        /**
         * The selection starts above where it ends.
         */
        LTR,
        /**
         * The selection starts below where it ends.
         */
        RTL
    }

    /**
     * A selection in the editor.
     * The selection is a range that has an orientation.
     */
    export class Selection extends vscMockRange.Range {
        /**
         * The line number on which the selection has started.
         */
        public readonly selectionStartLineNumber: number;
        /**
         * The column on `selectionStartLineNumber` where the selection has started.
         */
        public readonly selectionStartColumn: number;
        /**
         * The line number on which the selection has ended.
         */
        public readonly positionLineNumber: number;
        /**
         * The column on `positionLineNumber` where the selection has ended.
         */
        public readonly positionColumn: number;

        constructor(
            selectionStartLineNumber: number,
            selectionStartColumn: number,
            positionLineNumber: number,
            positionColumn: number
        ) {
            super(selectionStartLineNumber, selectionStartColumn, positionLineNumber, positionColumn);
            this.selectionStartLineNumber = selectionStartLineNumber;
            this.selectionStartColumn = selectionStartColumn;
            this.positionLineNumber = positionLineNumber;
            this.positionColumn = positionColumn;
        }

        /**
         * Clone this selection.
         */
        public clone(): Selection {
            return new Selection(
                this.selectionStartLineNumber,
                this.selectionStartColumn,
                this.positionLineNumber,
                this.positionColumn
            );
        }

        /**
         * Transform to a human-readable representation.
         */
        public toString(): string {
            return (
                '[' +
                this.selectionStartLineNumber +
                ',' +
                this.selectionStartColumn +
                ' -> ' +
                this.positionLineNumber +
                ',' +
                this.positionColumn +
                ']'
            );
        }

        /**
         * Test if equals other selection.
         */
        public equalsSelection(other: ISelection): boolean {
            return Selection.selectionsEqual(this, other);
        }

        /**
         * Test if the two selections are equal.
         */
        public static selectionsEqual(a: ISelection, b: ISelection): boolean {
            return (
                a.selectionStartLineNumber === b.selectionStartLineNumber &&
                a.selectionStartColumn === b.selectionStartColumn &&
                a.positionLineNumber === b.positionLineNumber &&
                a.positionColumn === b.positionColumn
            );
        }

        /**
         * Get directions (LTR or RTL).
         */
        public getDirection(): SelectionDirection {
            if (
                this.selectionStartLineNumber === this.startLineNumber &&
                this.selectionStartColumn === this.startColumn
            ) {
                return SelectionDirection.LTR;
            }
            return SelectionDirection.RTL;
        }

        /**
         * Create a new selection with a different `positionLineNumber` and `positionColumn`.
         */
        public setEndPosition(endLineNumber: number, endColumn: number): Selection {
            if (this.getDirection() === SelectionDirection.LTR) {
                return new Selection(this.startLineNumber, this.startColumn, endLineNumber, endColumn);
            }
            return new Selection(endLineNumber, endColumn, this.startLineNumber, this.startColumn);
        }

        /**
         * Get the position at `positionLineNumber` and `positionColumn`.
         */
        public getPosition(): vscMockPosition.Position {
            return new vscMockPosition.Position(this.positionLineNumber, this.positionColumn);
        }

        /**
         * Create a new selection with a different `selectionStartLineNumber` and `selectionStartColumn`.
         */
        public setStartPosition(startLineNumber: number, startColumn: number): Selection {
            if (this.getDirection() === SelectionDirection.LTR) {
                return new Selection(startLineNumber, startColumn, this.endLineNumber, this.endColumn);
            }
            return new Selection(this.endLineNumber, this.endColumn, startLineNumber, startColumn);
        }

        // ----

        /**
         * Create a `Selection` from one or two positions
         */
        public static fromPositions(
            start: vscMockPosition.IPosition,
            end: vscMockPosition.IPosition = start
        ): Selection {
            return new Selection(start.lineNumber, start.column, end.lineNumber, end.column);
        }

        /**
         * Create a `Selection` from an `ISelection`.
         */
        public static liftSelection(sel: ISelection): Selection {
            return new Selection(
                sel.selectionStartLineNumber,
                sel.selectionStartColumn,
                sel.positionLineNumber,
                sel.positionColumn
            );
        }

        /**
         * `a` equals `b`.
         */
        public static selectionsArrEqual(a: ISelection[], b: ISelection[]): boolean {
            if ((a && !b) || (!a && b)) {
                return false;
            }
            if (!a && !b) {
                return true;
            }
            if (a.length !== b.length) {
                return false;
            }
            for (var i = 0, len = a.length; i < len; i++) {
                if (!this.selectionsEqual(a[i], b[i])) {
                    return false;
                }
            }
            return true;
        }

        /**
         * Test if `obj` is an `ISelection`.
         */
        public static isISelection(obj: any): obj is ISelection {
            return (
                obj &&
                typeof obj.selectionStartLineNumber === 'number' &&
                typeof obj.selectionStartColumn === 'number' &&
                typeof obj.positionLineNumber === 'number' &&
                typeof obj.positionColumn === 'number'
            );
        }

        /**
         * Create with a direction.
         */
        public static createWithDirection(
            startLineNumber: number,
            startColumn: number,
            endLineNumber: number,
            endColumn: number,
            direction: SelectionDirection
        ): Selection {
            if (direction === SelectionDirection.LTR) {
                return new Selection(startLineNumber, startColumn, endLineNumber, endColumn);
            }

            return new Selection(endLineNumber, endColumn, startLineNumber, startColumn);
        }
    }
}
